package com.bite.spring.demo.Controller;

import com.bite.spring.demo.Student;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

// 添加类路径
@RequestMapping("/request")
// 注解告诉框架扫描这里
@RestController
public class RequestController {
    // 添加方法路径
    @RequestMapping("/m1")
    public String m1111(){
        System.out.println("hello String-boot-run!");// 控制台输出的
        return "hello String-boot-web!";// web 中看到的
    }

    // 基本数据类型不能传空值 error 400
    @RequestMapping("/m2")
    public int m2222(int number){
        return number;
    }

    // 包装类类型可以传空值 返回null
    @RequestMapping("/m3")
    public String m3333(Integer number){
        return "number:" + number;
    }

    // 传对象 key是对象里的属性
    @RequestMapping("/m4")
    public String m4444(Student student){
        return student.toString();
    }

    // 传数组 字符串自动拼接
    @RequestMapping("/m5")
    public String m555(String[] arr){
        return "strings:" + Arrays.toString(arr);
    }

    // 参数绑定 重命名前后端的参数值（前端加密时或取别名时）
    // 从前端接收参数赋值给password
    // 此时传参只能传‘q’ 不能传password （绑定）
    @RequestMapping("/m6")
    public String m6(@RequestParam("q") String password){
        return "password :" + password;
    }

    // 参数绑定
    // 如果找不到 q 就为 null
    // 参数名匹配 永远是精确匹配！！！
    // 传 password=1 依旧是null
    @RequestMapping("/m7")
    public String getPassword(@RequestParam(value = "q",required = false) String password){
        return "password :" + password;
    }

    // 传数组
    @RequestMapping("/m8")
    // 需要参数绑定
    // 把数组的参数绑定成一个list
    public String fun1(@RequestParam List<Integer> list) {
        return "list:" + list;
    }

    // 传栈
    @RequestMapping("/m9")
    // 容器需要参数绑定
    public String fun2(@RequestParam Stack<Integer> stack) {
        return  "stack:" + stack;
    }

    // 传队列
    @RequestMapping("/m10")
    // 容器需要参数绑定
    public String fun(@RequestParam PriorityQueue<Integer> queue) {
        return  queue.toString();
    }

    @RequestMapping("/m11")
    // @RequestBody 获取请求的 body 内容
    public String getPassword2(@RequestBody String password){
        return "password :" + password;
    }

    @RequestMapping("/m12")
    // 客户端传递 Json
    // 接收 Json 并把对应值传到 student 对象中
    public String m12(@RequestBody Student student){
        return "student:" + student.toString();
    }

    // 接收url资源信息
    @RequestMapping("/article/{articleId}")// 表示路径凡是符合/article/xxxx格式的都能获取到
    // @PathVariable 表示路径变量 articleId接收
    public String m13(@PathVariable Integer articleId){
       return "articleId:" + articleId;
    }

    @RequestMapping("/article/{type}/{articleId}")
    // 可以重命名 参数必传
    public String m14(@PathVariable("type") String articleType, @PathVariable Integer articleId){
        return  "articleId:" + articleId +  "; type:" + articleType;
    }

    //接收发送文件
    @RequestMapping("m15")
    // 使用 MultipartFile 类接收，支持多种的文件格式 如img/doc/pdf
    public String m15(MultipartFile file) throws IOException {
        String filename = file.getOriginalFilename();
//        // 文件上传保存至本地 new File 需要指定的是名称而不是路径
//        file.transferTo(new File("D:\\picture\\" + file.getOriginalFilename()));
        Resource fileResource = file.getResource();
        return "filename: " + filename + "; \n fileResource: " + fileResource;
    }

    // 接收Cookie
    @RequestMapping("/getCookie")
    public String getCookie(HttpServletRequest request){
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName() + ": " + cookie.getValue());
            }
        }else return "Cookie is null";

        return "返回cookie成功";
    }

    // 通过注解获得 Cookie
    @RequestMapping("/getCookie2")
    public String getCookie2(@CookieValue("java") String value) {
        return "Cookie.value = " + value;
    }

    // 存储 / 初始Session （服务器返回客户端Sessionid，值在服务器存储）
    // 通过拿到的Http请求来拿到里面的 cookie -> 里面存着 sessionId —> 拿到 session 对象
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request) {
        // 服务器根据 Cookie 获取 SessionId，再根据 SessionId 来判断是否有 session 对象
        HttpSession session = request.getSession();
        // 默认是如果没有则默认创建一个空的 session 对象（服务器创造）
        // 若设置false 则不会默认创建空 session 对象
//        HttpSession session = request.getSession(false);
//        if (session == null) return "session is null";

        // 可以往里存储值 (服务器给的)
        session.setAttribute("java",666);
        session.setAttribute("coke","god damn!");
        session.setAttribute("name","coke");
        return session.getId() + ": " + session.getAttribute("name").toString();
    }

    // 根据获得的session分辨用户是否有登录过
    @RequestMapping("/getSession")
    public String getSession(HttpServletRequest request) {
        // 不同的客户端对应不同的 SessionId，如果是第一次访问，服务器没有给他创建Session对象，则拿不到session内的信息
        // 服务器根据 Cookie 获取 SessionId，再根据 SessionId 来判断是否有 session 对象
        HttpSession session = request.getSession(false);// 用 false 来判定是否之前创建了会话
        if (session == null) {
            return "用户未登录";
        }else {
//            session.setAttribute("name","雨姐");
//            session.setAttribute("password",666);
//            return "用户已登录";
            String name = (String) session.getAttribute("name");
            return "用户名字为：" + name;
        }
    }

    // 还能通过HttpSession直接拿到session
    @RequestMapping("/getSession2")
    public String getSession2(HttpSession session) {
        if (session == null) return "用户未登录"; // 永远跳不到这一步 Spring会默认建造一个空对象
        // HttpSession会在底层调用request.getSession();
        // 如果有现有的则会返回现有的 如果没有则创建一个空的session对象
        return "用户名字为：" + (String) session.getAttribute("name");
    }

    // 更简要 通过注解拿到Session的具体值
    @RequestMapping("/getSession3")
    public String getSession3(@SessionAttribute("name") String sessionName) {
        return sessionName;
    }
}
